HPA
파드에 접근하는 사용자가 많아진다면 파드는 트래픽을 더 이상 감당할 수 없어서 서비스 불가(여기서 말하는 서비스는 쿠버네티스의 서비스가 아님)라는 결과를 초래할 수도 있다.
쿠버네티스는 이런 경우를 대비해 부하량에 따라 디플로이먼트의 파드 수를 유동적으로 관리하는 기능을 제공한다. 이를 HPA(Horizontal Pod Autoscaler)라고 한다.
부하량이 증가하게 되면 설정에 따라 파드를 더 배치하게 되고 부하가 감소하게되면 파드를 자동으로 감소시킨다.
실습
1. 디플로이먼트 1개를 hpa-hname-pods 라는 이름으로 생성해보자
$ kubectl create deployment hpa-hname-pods --image=sysnet4admin/echo-hname
deployment.apps/hpa-hname-pods created
2. 이전 게시글 [쿠버네티스 서비스 - Loadbalancer]에서 MetalLB를 구성했으므로 expose를 실행해 hpa-hname-pods를 로드밸런서 서비스로 바로 설정할 수 있다.
$ kubectl expose deployment hpa-hname-pods --type=LoadBalancer --name=hpa-hname-svc --port=80
service/hpa-hname-svc exposed
3. 설정된 로드밸런서 서비스와 부여된 IP를 확인해보자
$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
hpa-hname-svc LoadBalancer 10.111.76.23 192.168.1.11 80:32324/TCP 32s app=hpa-hname-pods
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d19h <none>
4. HPA가 작동하려면 파드의 자원이 어느 정도로 사용되는지 파약해야 한다. 부하를 확인하는 명령은 리눅스의 top과 비슷한 kubectl top pods이다.
$ kubectl top pods
Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
그런데 자원을 요청하는 설정이 없다며 에러가 생기고 진행되지 않는다. 왜 에러가 발생하는지 HPA가 작동하는 구조를 간단하게 살펴보자.
HPA가 자원을 요청할 때 메트릭 서버(Metrics-Server)를 통해 계측값을 전달 받는다. 그런데 현재 구성된 메트릭 서버가 없기 때문에 에러가 발생하는 것이다. 따라서 계측값을 수집하고 전달해 주는 메트릭 서버를 설정해주어야 한다.
💡
에러의 내용을 보면 서비스를 확인(get services http:heapster:)하도록 요청했다. 여기서 나온 힙스터는 쿠버네티스 1.13 이전 버전에서 사용하던 모니터링 도구이다. 1.13 버전부터는 메트릭 서버를 모니터링 도구로 추천한다.
5. 서비스에서와 마찬가지로 메트릭 서버또한 오브젝트 스펙파일로 설치가 가능하다.
https://github.com/kubernetes-sigs/metrics-server
해당 명령어를 실행시키면 메트릭 서버가 구성된다.
$ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Error from server (ServiceUnavailable): the server is currently unable to handle the request (get pods.metrics.k8s.io)
하지만 다시 top 명령어를 실행해도 위와 같은 에러메시지가 발생하며 정보를 불러오지 못한다.
이 현상은 TLS 인증이 되지 않아 발생하는 에러 메시지로 해당 실습에서는 해당 인증을 무시하도록 메트릭 서버를 수정해주어야 한다.
아래 명령어로 배포된 deployment의 수정이 가능하다.
$ kubectl edit deployment -n kube-system metrics-server
위 명령을 실행하여 편집기가 열리면 스크롤을 내려 args: 부분에 tls 인증을 무시할 수 있도록 아래 내용을 추가하고 저장한다.
- --kubelet-insecure-tls
그런데 저장을 하려고 하니 아래와 에러가 발생하였다.
error: Edit cancelled, no valid changes were saved.
edit 관련한 에러이고 [[k8s] Kubernetes edit Error](error: Edit cancelled, no valid changes were saved.) 해당 게시글을 참조하여 해결 가능하다.
하지만 현재 scale 기준 값이 설정되어 있지 않아 파드를 증설한 시점을 알 수 없기 때문에 파드에 scale이 실행되게 해당 파드에 edit 명령으로 기준 값을 설정해주어야 한다.
$ KUBE_EDITOR="vim" kubectl edit deployment hpa-hname-pods
deployment.apps/hpa-hname-pods edited
120행에 resources: {} 부분에 requests, limits 항목을 추가해주자.
여기서 사용한 m이라는 단위는 Milliunits의 약어로 1000m이 1cpu 이다.
requests: cpu: "10m"은 0.01cpu 사용을 기준으로 파드를 증설하게 설정한 것이고
한쪽 파드로 부하가 몰릴 것을 대비해 limits: cpu: "50m"으로 cpu 사용 제한을 0.05cpu로 설정하였다.
설정이 잘 적용되었다면 변경되고 정보 수집에 시간이 조금 걸리므로 1 ~ 2분 정도 경과 후 다시 kubectl top 명령어를 수행하면 아래와 같이 리소스를 정상적으로 모니터링 하는 것을 볼 수가 있을 것이다.
$ kubectl top pods
NAME CPU(cores) MEMORY(bytes)
hpa-hname-pods-75f874d48c-5gzp5 0m 1Mi
6. hpa-hname-pods에 autoscale을 설정하여 특정 조건이 만족되는 경우에 자동으로 scale 명령이 수행되도록 설정해보자.
$ kubectl autoscale deployment hpa-hname-pods --min=1 --max=30 --cpu-percent=50
horizontalpodautoscaler.autoscaling/hpa-hname-pods autoscaled
여기서 min은 최소 파드의 수, max는 최대 파드의 수이다. cpu-percent는 CPU 사용량이 50%를 넘게되면 autoscale 하겠다는 뜻.
7. 테스트를 위해 현재 마스터 노드의 터미널을 두 개 띄우고 왼쪽 창에서는 watch kubectl top pods
을, 오른쪽 창에서는 watch kubectl get pods
를 실행한다. 여기서 wawtch를 사용한 이유는 2초에 한 번씩 자동으로 상태를 확인하기 위해서이다.
부하를 줄 명령을 아래와 같이 실행해보자. 해당 명령을 실행하고 왼쪽 창에서 부하량을 감지하고 있는지 확인해보자.
$ i=1; while true; do sleep 1; echo "$(( i ++ )) - $(curl -s -X GET 192.168.1.11)"; done
7. 부하량이 늘어남에 따라 오른쪽 창에서 파드가 생성되는지 확인해보자
8. 부하 발생 코드를 종료하고 일정 시간 지난 후 더 이상 부하가 없으면 autoscale의 최소 조건인 파드 1개의 상태로 다시 돌아가는지 확인해보도록 하자.(시간이 조금 더 걸린다)
마무리
이렇게 부하 테스트를 완료했고 이와 같이 HPA를 잘 활용하면 자원 사용을 극대화 할 수 있고 서비스의 안정성을 높일 수 있다.